import {
  ReactNode,
  forwardRef,
  useEffect,
  useImperativeHandle,
  useState,
  memo,
} from "react";
import { Button, Form, Input, DatePicker, Upload, Modal } from "antd";
import styles from "./index.module.css";
import { PlusOutlined } from "@ant-design/icons";
import type { RcFile, UploadFile, UploadProps } from "antd/es/upload/interface";
import { FromComProp, FormFiledProp } from "../../type/form";
import { timeEcho } from "../../untils/date";

const { RangePicker } = DatePicker;
const Index = forwardRef((props: FromComProp, ref) => {
  const [fileList, setFileList] = useState<UploadFile[]>([]);
  const [previewOpen, setPreviewOpen] = useState(false);
  const [previewImage, setPreviewImage] = useState<string>("");
  const [previewTitle, setPreviewTitle] = useState<string>("");
  const [form] = Form.useForm();
  const {
    FormFiledList,
    formId,
    Success,
    Failed,
    hasModal,
    editData,
    detailid,
  } = props;
  useEffect(() => {
    getEditData();
  }, [editData, detailid]);
  const getEditData = async () => {
    if (detailid && detailid.toString() !== "0") {
      if (!editData.activeImgUrl) {
        form.setFieldsValue(editData);
      } else {
        editData.activeTime = timeEcho(
          editData.activeStartTime,
          editData.activeEndTime,
          "YYYY/MM/DD"
        );
        setFileList(editData.activeImgUrl);
        form.setFieldsValue(editData);
      }
    } else {
      rest();
    }
  };
  const onFinish = (values: FormFiledProp) => {
    Success && Success(values);
  };
  const rest = () => {
    setFileList([]);
    form.resetFields();
  };
  useImperativeHandle(ref, () => {
    return {
      getFormValue: getFormValue,
      validateForm: form.validateFields,
      setFormValues: form.setFieldsValue,
      restFormValue: form.resetFields,
      restForm: rest,
    };
  });
  const getFormValue = () => {
    const formValue = form.getFieldsValue();
    const isEdit =
      detailid && detailid.toString() !== "0"
        ? { ...formValue, id: detailid }
        : formValue;
    return isEdit;
  };
  const onFinishFailed = (errorInfo: any) => {
    Failed && Failed(errorInfo);
  };

  const getBase64 = (file: RcFile): Promise<string> =>
    new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => resolve(reader.result as string);
      reader.onerror = (error) => reject(error);
    });
  const handleCancel = () => setPreviewOpen(false);

  const handlePreview = async (file: UploadFile) => {
    if (!file.url && !file.preview) {
      file.preview = await getBase64(file.originFileObj as RcFile);
    }

    setPreviewImage(file.url || (file.preview as string));
    setPreviewOpen(true);
    setPreviewTitle(
      file.name || file.url!.substring(file.url!.lastIndexOf("/") + 1)
    );
  };

  const handleChange: UploadProps["onChange"] = ({ fileList: newFileList }) =>
    setFileList(newFileList);

  const uploadButton = (
    <div>
      <PlusOutlined />
      <div style={{ marginTop: 8 }}>Upload</div>
    </div>
  );
  const shouldReturnEle = (nodeType: any): ReactNode => {
    const { type } = nodeType;
    if (type === "Input") {
      return <Input />;
    } else if (type === "Password") {
      return <Input.Password />;
    } else if (type === "DatePicker") {
      return <RangePicker format="YYYY/MM/DD" />;
    } else if (type === "Image") {
      return (
        <div>
          <Upload
            action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
            listType="picture-card"
            fileList={fileList}
            onPreview={handlePreview}
            onChange={handleChange}
          >
            {fileList.length >= 8 ? null : uploadButton}
          </Upload>
          <Modal
            open={previewOpen}
            title={previewTitle}
            footer={null}
            onCancel={handleCancel}
          >
            <img alt="example" style={{ width: "100%" }} src={previewImage} />
          </Modal>
        </div>
      );
    }
  };
  const normFile = (e: any) => {
    if (Array.isArray(e)) {
      return e;
    }
    return e;
  };
  return (
    <>
      <Form
        name={formId}
        form={form}
        className={styles.container}
        initialValues={{ remember: true }}
        onFinish={onFinish}
        onFinishFailed={onFinishFailed}
        autoComplete="off"
      >
        {FormFiledList.map((ite) => {
          const { required, message, name, type, label } = ite;
          if (type === "Image") {
            return (
              <Form.Item
                key={`${label}+${name}`}
                label={label}
                name={name}
                // valuePropName={"fileList"}
                getValueFromEvent={normFile}
                rules={
                  required && message
                    ? [
                        {
                          required: required,
                          message: message,
                        },
                      ]
                    : []
                }
              >
                {shouldReturnEle(ite)}
              </Form.Item>
            );
          }
          return (
            <Form.Item
              key={`${label}+${name}`}
              label={label}
              name={name}
              rules={
                required && message
                  ? [
                      {
                        required: required,
                        message: message,
                      },
                    ]
                  : []
              }
            >
              {shouldReturnEle(ite)}
            </Form.Item>
          );
        })}
        {hasModal ? (
          <Form.Item>
            <Button type="primary" htmlType="submit">
              submit
            </Button>{" "}
          </Form.Item>
        ) : (
          ""
        )}
      </Form>
    </>
  );
});
export default memo(Index);
